package com.moefor.clover.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import org.hibernate.Hibernate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.moefor.clover.model.Comment;
import com.moefor.clover.model.Goods;
import com.moefor.clover.model.Message;
import com.moefor.clover.model.Order;
import com.moefor.clover.model.User;
import com.moefor.clover.model.enums.CloverSessionKey;
import com.moefor.clover.model.enums.StateOfGoods;
import com.moefor.clover.model.enums.StateOfOrder;
import com.moefor.clover.service.CommunicationService;
import com.moefor.clover.service.ShopService;
import com.moefor.clover.service.UserService;
import com.moefor.clover.util.MessagePackager;

@Controller
public class ViewController {
	@Resource
	private UserService userService;
	
	@Resource
	private ShopService shopService;
	
	@Resource
	private CommunicationService communicationService;
	
	private Map<String,Object> putBaseInfo(HttpSession session, Map<String,Object> model){
		User user = (User)session.getAttribute(CloverSessionKey.USER);
		if(user != null){
			//Set<Message> msgSet = (Set<Message>)communicationService.getUnreadMessage(user.getId()).getData();
			
			MessagePackager msgPack = communicationService.getUnreadMessage(user.getId());
			if(msgPack.getState()){
				List<Message> msgList = new ArrayList<Message>((Set<Message>)msgPack.getData());
				Collections.sort(msgList, new Comparator<Message>() {
		            public int compare(Message arg0, Message arg1) {
		            	return arg1.getDate().compareTo(arg0.getDate());
		            }
		        });
				
				Set<Message> msgSet = new HashSet<Message>();
				for(int i=0; i<msgList.size(); i++){
					msgSet.add(msgList.get(i));
					if(i>=4) break;
				}
				model.put("msgSet", msgSet);
			}
			model.put("user", user);
		}
		return model;
	}
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	public ModelAndView index(HttpSession session){
		return new ModelAndView("home");
	}
	
	@RequestMapping(value = "/home.page", method = RequestMethod.GET)
	public ModelAndView home(HttpSession session){
		Map<String,Object> model = new HashMap<String,Object>(); 
		putBaseInfo(session, model);
		return new ModelAndView("home", model);
	}
	
	@RequestMapping(value = "/deal.page", method = RequestMethod.GET)
	public ModelAndView deal(HttpSession session){
		Map<String,Object> model = new HashMap<String,Object>(); 
		//WAIT_FOR_CFMD, DEAL, CLOSED, FINISHED
		putBaseInfo(session, model);
		User u = (User)model.get("user");
		
		MessagePackager msgPack = shopService.getGoodsByOwnerId(u.getId());
		if(msgPack.getState()){
			List<Goods> sellGoodsList = new ArrayList<Goods>();
			List<StateOfGoods> goodsStateList = new ArrayList<StateOfGoods>();
			goodsStateList.add(StateOfGoods.ON_SALE);
			goodsStateList.add(StateOfGoods.SOLD);
			goodsStateList.add(StateOfGoods.BAN);
			for(StateOfGoods state : goodsStateList){
				for(Goods g : (Set<Goods>)msgPack.getData()){
					if(g.getState().equals(state)){
						sellGoodsList.add(g);
					}
				}
			}
			model.put("sellGoodsItems", sellGoodsList);
		}
		
		List<StateOfOrder> stateList = new ArrayList<StateOfOrder>();
		stateList.add(StateOfOrder.WAIT_FOR_CFMD);
		stateList.add(StateOfOrder.FINISHED);
		
		List<Order> buyOrderList = new ArrayList<Order>();
		for(StateOfOrder state : stateList){
			msgPack = shopService.getOrderByCustomer(u.getId(), state);
			List<Order> tmpList = new ArrayList<Order>();
			if(msgPack.getState()){
				tmpList.addAll((Set<Order>)msgPack.getData());
				Collections.sort(tmpList, new Comparator<Order>() {
		            public int compare(Order arg0, Order arg1) {
		            	return arg1.getDate().compareTo(arg0.getDate());
		            }
		        });
			}
			buyOrderList.addAll(tmpList);
		}
		
		model.put("buyOrderItems", buyOrderList);
		
		return new ModelAndView("deal", model);
	}
	
	@RequestMapping(value = "/onsale.page", method = RequestMethod.GET)
	public ModelAndView onsale(HttpSession session){
		Map<String,Object> model = new HashMap<String,Object>(); 
		putBaseInfo(session, model);
		
		User u = (User)model.get("user");
		
		u = (User)userService.get(u.getId()).getData();
		
		Hibernate.initialize(u.getGoodsItems());
		for(Goods g : u.getGoodsItems()){
			Hibernate.initialize(g.getCommentItems());
		}
		model.put("goodsItems", u.getGoodsItems());
		return new ModelAndView("onsale", model);
	}
	
	@RequestMapping(value = "/favorite.page", method = RequestMethod.GET)
	public ModelAndView favorite(HttpSession session){
		Map<String,Object> model = new HashMap<String,Object>(); 
		putBaseInfo(session, model);
		return new ModelAndView("favorite", model);
	}
	
	@RequestMapping(value = "/userinfo.page", method = RequestMethod.GET)
	public ModelAndView userinfo(HttpSession session){
		Map<String,Object> model = new HashMap<String,Object>(); 
		putBaseInfo(session, model);
		User u = (User)model.get("user");
		if(u == null) return new ModelAndView("home", model);
		MessagePackager msgPack = communicationService.getMessageByReceiver(u.getId());	
		List<Message> msgList = new ArrayList<Message>();
		if(msgPack.getState()){
			msgList.addAll(((Set<Message>)msgPack.getData()));
			Collections.sort(msgList, new Comparator<Message>() {
	            public int compare(Message arg0, Message arg1) {
	            	return arg1.getDate().compareTo(arg0.getDate());
	            }
	        });
		}
		model.put("msgItems", msgList);
		
		return new ModelAndView("userinfo", model);
	}
	
	@RequestMapping(value = "/allsale.page", method = RequestMethod.GET)
	public ModelAndView allsale(HttpSession session,
			@RequestParam(value = "userid", required=false) Integer userId){
		Map<String,Object> model = new HashMap<String,Object>(); 
		putBaseInfo(session, model);
		if(userId == null) return new ModelAndView("home", model);
		MessagePackager msgPack = userService.get(userId);
		if(!msgPack.getState()) return new ModelAndView("home", model);
		User u = (User)msgPack.getData();
		
		Hibernate.initialize(u.getGoodsItems());
		for(Goods g : u.getGoodsItems()){
			Hibernate.initialize(g.getCommentItems());
		}
		model.put("goodsItems", u.getGoodsItems());
		
		return new ModelAndView("allsale", model);
	}
	
	@RequestMapping(value = "/item.page", method = RequestMethod.GET)
	public ModelAndView item(HttpSession session,
			@RequestParam(value = "goodsid", required=false) Integer goodsId){
		Map<String,Object> model = new HashMap<String,Object>(); 
		putBaseInfo(session, model);
		
		if(goodsId == null )return new ModelAndView("home", model);
		MessagePackager msgPack = shopService.getGoods(goodsId);
		if(!msgPack.getState()) return new ModelAndView("home", model);
		Goods g = (Goods)msgPack.getData();
		Hibernate.initialize(g.getCommentItems());
		List<Comment> commentList = new ArrayList<Comment>(); 
		commentList.addAll(g.getCommentItems());
		Collections.sort(commentList, new Comparator<Comment>() {
            public int compare(Comment arg0, Comment arg1) {
            	return arg1.getDate().compareTo(arg0.getDate());
            }
        });
		model.put("goods", g);
		model.put("commentItems", commentList);
		model.put("owner", g.getOwner());
		
		User u = g.getOwner();
		Hibernate.initialize(u.getGoodsItems());
		model.put("otherGoods", u.getGoodsItems());
		
		return new ModelAndView("item", model);
	}
	
	@RequestMapping(value = "/sign.page", method = RequestMethod.GET)
	public ModelAndView sign(HttpSession session){
		User user = (User)session.getAttribute(CloverSessionKey.USER);
		if(user == null)
			return new ModelAndView("sign");
		else
			return new ModelAndView("home");
	}
	
}
